package com.deer.wms.base.system.service.task.impl;

import com.deer.wms.base.system.dao.task.TaskInfoMapper;
import com.deer.wms.base.system.finalUtil.CellInfoState;
import com.deer.wms.base.system.model.Rocket;
import com.deer.wms.base.system.model.box.BoxInfo;
import com.deer.wms.base.system.model.box.BoxItem;
import com.deer.wms.base.system.model.box.BoxItemDto;
import com.deer.wms.base.system.model.task.*;
import com.deer.wms.base.system.model.ware.CellInfo;
import com.deer.wms.base.system.service.box.BoxInfoService;
import com.deer.wms.base.system.service.box.IBoxItemService;
//import com.deer.wms.base.system.service.rabbitMQ.MsgProducer;
import com.deer.wms.base.system.service.task.ITaskInfoService;
import com.deer.wms.base.system.service.task.PickTaskService;
import com.deer.wms.base.system.service.ware.ICellInfoService;
import com.deer.wms.common.core.service.AbstractService;
import com.deer.wms.common.core.text.Convert;
import com.deer.wms.common.utils.TaskNumberUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

/**
 * 任务 服务层实现
 *
 * @author guo
 * @date 2019-06-03
 */
@Service
@Transactional
public class TaskInfoServiceImpl extends AbstractService<TaskInfo, Integer> implements ITaskInfoService {

    @Autowired
    private TaskNumberUtil taskNumberUtil;

    @Autowired
    private TaskInfoMapper taskInfoMapper;

    @Autowired
    private ICellInfoService cellInfoService;

    @Autowired
    private IBoxItemService boxItemService;

    @Autowired
    private ITaskInfoService taskInfoService;

    @Autowired
    private BoxInfoService boxInfoService;

    @Autowired
    private BillInTaskInfoServiceImpl billInTaskInfoService;

    @Autowired
    private PickTaskService pickTaskService;

	/*@Autowired
	private MsgProducer msgProducer;*/

    @Override
    public int getCountByBillIdAndReceipt(TaskInfoCriteria criteria) {
        return taskInfoMapper.getCountByBillIdAndReceipt(criteria);
    }

    /**
     * 根据出库单id查找出库单的所有任务信息
     *
     * @param billId
     * @return
     */
    @Override
    public List<TaskInfo> selectTaskInfoByBillOutMasterId(Integer billId) {

        return taskInfoMapper.selectTaskInfoByBillOutMasterId(billId);
    }


    /**
     * WCS完成任务后的回调处理
     *
     * @param taskId
     * @param state
     */
    @Override
    public void finishTask(String taskId, Integer state) {

        TaskInfo taskInfo = taskInfoService.getTaskInfoByTaskId(taskId);
        if (taskInfo != null) {

            taskInfo.setState(state);
            taskInfoService.updateTaskInfo(taskInfo);

            //获得该任务的类型(可参考数据库注释)
            int type = taskInfo.getType();

            //1-入库任务(将空/半空托盘从货位上移到固定位置)
            if (state == 3 && type == 1) {


//				System.out.println("44444444444444444444444444444444");
//				System.out.println("44444444444444444444444444444444");
//				System.out.println("44444444444444444444444444444444");


//				//将货位状态改成0
//				CellInfo cellInfo = cellInfoService.getCellInfoByTaskId(taskId);
//				cellInfo.setState(0);
//				cellInfoService.updateCellInfo(cellInfo);
//
//				//将容器表中的boxCellId改为null
//				BoxInfo boxInfo = boxInfoService.getBoxInfoByTaskId(taskId);
//				boxInfo.setBoxCellId(null);
//				//设置托盘状态为0，托盘离开货位
//				boxInfo.setBoxState(0);
//				boxInfoService.update(boxInfo);

            }

            //2-入库任务(当托盘已经到达装货点，装货完毕后   寻找合适的货位返回)
            if (state == 3 && type == 2) {

                //将货位状态改成0
                CellInfo cellInfo = cellInfoService.getCellInfoByTaskId(taskId);

                int cellId = cellInfo.getCellId();

                cellInfo.setState(1);
                cellInfoService.updateCellInfo(cellInfo);

                //将容器表中的boxCellId改为cellId
                BoxInfo boxInfo = boxInfoService.getBoxInfoByTaskId(taskId);
                boxInfo.setBoxCellId(cellId);
                //设置托盘状态为1，托盘进入货位
                boxInfo.setBoxState(1);
                boxInfoService.update(boxInfo);

            }

            //3-出库任务(根据货物编码  以及需要出库的数量，生成需要的N条任务信息，将合适的托盘移到固定位置/卸货位置)
            if (state == 3 && type == 3) {

                //将货位状态改为0
                CellInfo cellInfo = cellInfoService.getCellInfoByTaskId(taskId);
                cellInfo.setState(0);
                cellInfoService.updateCellInfo(cellInfo);

                //将托盘中的数量清零
                BoxItem boxItem = boxItemService.getBoxItemByTaskId(taskId);
                //boxItem.setQuantity(0);
                //设置托盘状态为0，托盘离开货位
                //BoxInfo boxInfo = boxInfoService.getBoxInfoByBoxCode(taskInfo.getBoxCode());
                //boxInfo.setBoxState(0);
                //boxInfoService.update(boxInfo);
            }

            //4-根据托盘编码 ， 将托盘放置空货位上
            if (state == 3 && type == 4) {

                //将货位状态改为1
                CellInfo cellInfo = cellInfoService.getCellInfoByTaskId(taskId);
                cellInfo.setState(1);
                cellInfoService.updateCellInfo(cellInfo);

                int cellId = cellInfo.getCellId();
                //向该货位增加托盘， 根据托盘编码查出该托盘，并将托盘表boxInfo中的  货位id字段绑定
                //BoxInfo boxInfo = boxInfoService.getBoxInfoByBoxCode(taskInfo.getBoxCode());
                //boxInfo.setBoxCellId(cellId);
                //设置托盘状态为1，托盘进入货位
                //boxInfo.setBoxState(1);
                //boxInfoService.update(boxInfo);

            }

            //5-出库任务-将有合适货物的托盘调度到出货口(固定位置)
            if (state == 3 && type == 5) {

                //将货位状态改为0
                CellInfo cellInfo = cellInfoService.getCellInfoByTaskId(taskId);
                cellInfo.setState(0);
                cellInfoService.updateCellInfo(cellInfo);

                //将托盘表中绑定的cellid设置为null  解绑
                //BoxInfo boxInfo = boxInfoService.getBoxInfoByBoxCode(taskInfo.getBoxCode());
                //boxInfo.setBoxCellId(null);
                //设置托盘状态为0，托盘离开货位
                //boxInfo.setBoxState(0);
                //boxInfoService.update(boxInfo);

                //将托盘中的数量设置为(原有的数量 - pick的数量)
                //BoxItem boxItem = boxItemService.getBoxItemByBoxCode(taskInfo.getBoxCode());
                //PickTask pickTask = pickTaskService.getPickTaskByBoxItemId(boxItem.getId());
                //boxItem.setQuantity(boxItem.getQuantity() - pickTask.getPickQuantity());
                //boxItemService.updateBoxItem(boxItem);


            }


        }

    }

    /**
     * 根据任务ID查询任务信息，便于更改状态值
     *
     * @param taskId
     * @return
     */
    @Override
    public TaskInfo getTaskInfoByTaskId(String taskId) {

        return taskInfoMapper.getTaskInfoByTaskId(taskId);
    }


    /**
     * 根据billInMasterId查询任务列表
     *
     * @param billId
     * @return
     */
    @Override
    public List<TaskInfoDto> selectTaskInfoByBillInMasterId(Integer billId) {

        return taskInfoMapper.selectTaskInfoByBillInMasterId(billId);
    }

    @Override
    public TaskInfoDto selectTaskInfoByid(Integer id) {
        return taskInfoMapper.selectTaskInfoByid(id);
    }

    /**
     * 查询状态值为0的任务，(为WCS提供接口)
     *
     * @return
     */
    @Override
    public List<TaskInfoWcs> selectTaskInfoForWcsByState() {

        return taskInfoMapper.selectTaskInfoForWcsByState();
    }

    /**
     * 查询任务信息
     *
     * @param id 任务ID
     * @return 任务信息
     */
    @Override
    public TaskInfo selectTaskInfoById(Integer id) {
        return taskInfoMapper.selectTaskInfoById(id);
    }

    /**
     * 查询任务列表
     *
     * @param taskInfo 任务信息
     * @return 任务集合
     */
    @Override
    public List<TaskInfo> selectTaskInfoList(TaskInfo taskInfo) {
        return taskInfoMapper.selectTaskInfoList(taskInfo);
    }


    /**
     * 新增任务
     *
     * @param taskInfo 任务信息
     * @return 结果
     */
    @Override
    public int insertTaskInfo(TaskInfo taskInfo) {
        return taskInfoMapper.insertTaskInfo(taskInfo);
    }

    @Override
    public int insertBillInTaskInfo(TaskInfo taskInfo) {
        return taskInfoMapper.insertBillInTaskInfo(taskInfo);
    }

    /**
     * 修改任务
     *
     * @param taskInfo 任务信息
     * @return 结果
     */
    @Override
    public int updateTaskInfo(TaskInfo taskInfo) {
        return taskInfoMapper.updateTaskInfo(taskInfo);
    }

    @Override
    public int updateZuPan(TaskInfo taskInfo) {
        return taskInfoMapper.updateZuPan(taskInfo);
    }

    /**
     * 删除任务对象
     *
     * @param ids 需要删除的数据ID
     * @return 结果
     */
    @Override
    public int deleteTaskInfoByIds(String ids) {
        return taskInfoMapper.deleteTaskInfoByIds(Convert.toStrArray(ids));
    }

    @Override
    public int deleteTaskInfoById(Integer id) {
        return taskInfoMapper.deleteTaskInfoById(id);
    }


    public List<TaskInfoDto> findList(TaskInfoCriteria criteria) {
        return taskInfoMapper.findList(criteria);
    }
    /***
     *查询出库任务
     * @param criteria
     * @author 李帅辰
     * @date 2020/9/30 15:43 
     * @return java.util.List<com.deer.wms.base.system.model.task.TaskInfoDto>
     */
    @Override
    public List<TaskInfoDto> billOutfindList(TaskInfoCriteria criteria) {
        return taskInfoMapper.billOutfindList(criteria);
    }

    @Override
    public List<TaskInfoDto> moveTaskfindList(TaskInfoCriteria criteria) {
        List<TaskInfoDto> taskInfoDtos = taskInfoMapper.moveTaskfindList(criteria);
        for (TaskInfoDto taskInfoDto : taskInfoDtos) {
            //Integer moveAimCid = taskInfoDto.getMoveAimCid();
//            if (null != moveAimCid){
//                CellInfo cellInfo = cellInfoService.selectCellInfoById(moveAimCid);
//                String memo = cellInfo.getMemo();
//                //taskInfoDto.setMoveTaskAimCell(memo);
//            }
        }
        return taskInfoDtos;
    }

    /***
     *入库任务
     * @param criteria
     * @author 李帅辰
     * @date 2020/9/30 10:26
     * @return java.util.List<com.deer.wms.base.system.model.task.TaskInfoDto>
     */
    @Override
    public List<TaskInfoDto> billInFindList(TaskInfoCriteria criteria) {
        return taskInfoMapper.billInFindList(criteria);
    }

    public TaskInfo findByItemCodeAndBatchAndExp(TaskInfoCriteria criteria) {
        return taskInfoMapper.findByItemCodeAndBatchAndExp(criteria);
    }

    @Override
    public List<TaskInfo> selectTaskInfoBybillId(Integer billId) {
        return taskInfoMapper.selectTaskInfoBybillId(billId);
    }


    /**
     * 设置任务的货位信息
     * @author 申紫微
     * @date 14:00 2020/9/8
     * @params taskInfo
     * @params boxCode
     * @params itemId
     * @params roadWay
     * @return boolean
     **/
    @Override
    public boolean setTaskInfoCellInfo(TaskInfo taskInfo,Integer currentItemId, Integer roadWay) {
        // 设置taskInfo的货位信息
        return handleTaskInfo(taskInfo, currentItemId, roadWay);
    }

    @Override
    public TaskInfoDto selectTaskInfoByBoxCode(String boxCode) {
        return taskInfoMapper.selectTaskInfoByBoxCode(boxCode);
    }

    /**
     * 校验当前托盘在任务表中是否仍然存在
     * @author 申紫微
     * @date 23:44 2020/11/23
     * @params boxCode
     * @return com.deer.wms.base.system.model.task.TaskInfo
     **/
    @Override
    public TaskInfo selectHaveOldTaskInfoByBoxCode(String boxCode){
        TaskInfo taskInfo = taskInfoMapper.selectHaveOldTaskInfoByBoxCode(boxCode);
        return taskInfo;
    }
    /**
     * 设置taskInfo的货位信息
     * @author 申紫微
     * @date 17:07 2020/9/8
     * @params taskInfo
     * @params currentItemId
     * @params roadWay
     * @return boolean
     **/
    private int startIndex = 0;
    private boolean  handleTaskInfo(TaskInfo taskInfo, Integer currentItemId, Integer roadWay) {
        // 获取用户选择的当前巷道的空货位数据
        // 查询从下标为0开始的十条数据,传入的roadWay不为空，则查询的是当前巷道的空货位，为空则查询的是所有巷道的空货位
        List<CellInfo> cellBlankList = new ArrayList<>();
        if (null != roadWay) {
            Integer blankCellCount = cellInfoService.checkBlankCellCountByRoadWay(roadWay);
            if (blankCellCount <= 6) {
                return false;
            }
            cellBlankList = cellInfoService.selectTopBlankCellInfoByRoadWay(roadWay, startIndex);
        } else {
            // 获取空货位的数量
            Integer blankCellCount = cellInfoService.checkBlankCellCount();
            // 3个巷道，每个巷道留下4个货位用来倒货，总共12个空位,有12个空位视为满库存状态
            if (blankCellCount <= 18) {
                return false;
            }
            cellBlankList = cellInfoService.selectTopBlankCellInfoByRoadWay(roadWay, startIndex);
        }
        // 获取任务号
        long taskNumber = generateTaskNumber();
        // 每次查询10条空货位数据,遍历查到的空库位信息，确定满足放货条件的空货位
        for (CellInfo info : cellBlankList) {
            int teamPai = info.getTeamPai();
            //空库位为当前巷道中的偶数排，也就是外侧的排，所以需要判断内侧排的物料品类
            if (0 != teamPai && 0 == teamPai % 2) {
                // 获取内侧货位的状态, 需要roadWay,teamPai,sLie,sFloor;  (teamPai - 1) 就是获取远离堆垛机一侧的货位排数
                //CellInfo cellTmp = cellInfoService.checkSideCellStatus(info.getTeamNumber(), teamPai - 1, info.getsLie(), info.getsFloor());
                // 校验当前货位的内侧货位不是空,且内侧货位放的货的品类和当前空货位即将要放的货品类一致,
                // 一致则进入，使用当前的空货位信息
//                if (cellTmp.getState() != 0 && cellTmp.getItemId().equals(currentItemId)) {
//                    String cellCode = handleCellCode(info.getsPai(), info.getsLie(), info.getsFloor());
//                    taskInfo.setCellCode(cellCode);
//                    //taskInfo.setRoadWay(roadWay != null ? roadWay : info.getTeamNumber());
//                    taskInfo.setTaskNumber(taskNumber);
//                    taskInfo.setCellId(cellTmp.getCellId());
//                    return true;
//                }
            } else if (0 != teamPai % 2) { // 处理奇数排货位
                //奇数货位正常情况是可以直接放货的，但为了避免遇到偶数货位有货，奇数货位无货的特殊情况，所以需要对偶数货位进行判断
                //CellInfo cellTmp = cellInfoService.checkSideCellStatus(info.getTeamNumber(), teamPai + 1, info.getsLie(), info.getsFloor());
                // 偶数货位状态为空，说明奇数货位可以进货，不会发生撞货现象
//                if (cellTmp.getState() == 0) {
////                    String cellCode = handleCellCode(info.getsPai(), info.getsLie(), info.getsFloor());
////                    taskInfo.setCellCode(cellCode);
////                    //taskInfo.setRoadWay(roadWay != null ? roadWay : info.getTeamNumber());
////                    taskInfo.setTaskNumber(taskNumber);
////                    taskInfo.setCellId(cellTmp.getCellId());
////                    return true;
////                }
            }
        }
        // 执行到这里说明上面的查询都不满足条件,下标偏移，继续查询
        startIndex += 10;
        return handleTaskInfo(taskInfo,currentItemId,roadWay);
    }

    /**
     * 获取任务号
     * @author 申紫微
     * @date 10:25 2020/9/9
     * @params
     * @return long
     **/
    public long generateTaskNumber(){
        long taskNumber = taskNumberUtil.generatorTaskNumberByNanoTime();
        if (taskNumber<10000){
            taskNumber+=10000;
        }
        TaskInfo entity = taskInfoMapper.selectTaskInfoByTaskNumber(taskNumber);
        TaskInfo billInTaskInfo = billInTaskInfoService.selectTaskInfoByTaskNumber(taskNumber);
        // 如果任务号存在，则递归调用，直到找到任务号不存在的随机数
        if (null == entity && null == billInTaskInfo) {
            return taskNumber;
        }
        return generateTaskNumber();
    }



    @Override
    public Rocket getMessAgeId(Integer id) {
        return taskInfoMapper.getMessAgeId(id);
    }

    @Override
    public List<TaskInfoDto> selectTaskInfoByBillOutId(Integer billId) {
        return taskInfoMapper.selectTaskInfoByBillOutId(billId);
    }

    @Override
    public TaskInfoDto findTaskInfoByTaskNumber(Long taskNumber) {
        return taskInfoMapper.findTaskInfoByTaskNumber(taskNumber);
    }

    @Override
    public TaskInfo selectTaskInfoByTaskNumber(long taskNumber) {
        return taskInfoMapper.selectTaskInfoByTaskNumber(taskNumber);
    }

    @Override
    public TaskInfoDto selectTaskInfoByMaterialId(String materialId) {
        return taskInfoMapper.selectTaskInfoByMaterialId(materialId);
    }

    @Override
    public boolean moveTaskForceComplete(int id) {
        TaskInfo taskInfo = selectTaskInfoById(id);
        if (null != taskInfo){
            // 修改移库任务的托盘的库存
            //String boxCode = taskInfo.getBoxCode();
            // 移库源货位id
            Integer srcCellId = taskInfo.getCellId();
            // 移库目标货位id
            //Integer moveAimCid = taskInfo.getMoveAimCid();

            // 设置托盘的货位为新的货位
            //BoxInfo boxInfo = boxInfoService.getBoxInfoByBoxCode(boxCode);
            //boxInfo.setBoxCellId(moveAimCid);
            //int boxInfoRes = boxInfoService.updateBoxInfo(boxInfo);
            // 设置移库目标货位为有货
            //CellInfo moveAimCell = cellInfoService.selectCellInfoById(moveAimCid);
            //moveAimCell.setState(CellInfoState.STATE_ONT);
            //int moveAimRes = cellInfoService.updateCellInfo(moveAimCell);
            // 设置源货位状态为无货
            CellInfo srcCell = cellInfoService.selectCellInfoById(srcCellId);
            srcCell.setState(CellInfoState.STATE_ZERO);
            int srcRes = cellInfoService.updateCellInfo(srcCell);
//            if (boxInfoRes > 0 && moveAimRes > 0 && srcRes > 0){
//                return true;
//            }
        }
        return false;
    }

    @Override
    public List<TaskInfoDto> findBillOutWorkList(TaskInfoDto taskInfoDto) {
        return taskInfoMapper.findBillOutWorkList(taskInfoDto);
    }

    @Override
    public List<TaskInfoDto> findTaskWorkList(TaskInfoDto taskInfoDto) {
        return taskInfoMapper.findTaskWorkList(taskInfoDto);
    }

    /**
     * 拼接货位信息
     * @author 申紫微
     * @date 17:13 2020/9/8
     * @params pai`
     * @params lie
     * @params ceng
     * @return java.lang.String
     **/
    private String handleCellCode(int pai, int lie, int ceng){
        StringBuilder sb = new StringBuilder();
        sb.append(String.format("%02d", pai))
                .append(String.format("%03d", lie))
                .append(String.format("%02d", ceng));
        return sb.toString();
    }

    public void save(TaskInfo taskInfo) {
        super.save(taskInfo);
		/*msgProducer.sendMsg(JSONArray.toJSONString(
				new TaskInfoWcs(taskInfo.getTaskId(),taskInfo.getStartPosition(),taskInfo.getEndPosition(),
						taskInfo.getType().toString(),taskInfo.getState().toString(), DateUtils.getTime(),taskInfo.getIsTop(),
						taskInfo.getBarCode(),taskInfo.getQuantity()
		)));*/
    }

    public static void main(String[] args) {
        int a = 6;
        int b = a % 2;
        int c = a / 2;
        System.out.println("1234r");
    }
}
